home *** CD-ROM | disk | FTP | other *** search
- #ifndef XPKMASTER_OPEN_C
- #define XPKMASTER_OPEN_C
-
- /* Routinesheader
-
- Name: open.c
- Main: xpkmaster
- Versionstring: $VER: open.c 1.7 (31.03.97)
- Author: SDI
- Distribution: PD
- Description: Opening and initialisation routines for XPK files
-
- 1.0 06.10.96 : first real version
- 1.1 28.10.96 : reincluded A4 support
- 1.2 03.03.97 : added Prefs, corrected length recognition
- 1.3 07.03.97 : fixed prefs handling, new features
- 1.4 09.03.97 : added DEBUG statement
- 1.5 28.03.97 : auto decrunch password
- 1.6 29.03.97 : fixed prefs stuff, moved getinlen into hooks
- 1.7 31.03.97 : changed the password stuff
- */
-
- #include <exec/types.h>
- #include <dos/dos.h>
- #include <xpk/xpkprefs.h>
- #include <exec/memory.h>
- #include <pragma/exec_lib.h>
- #include <pragma/dos_lib.h>
- #include <pragma/xpkmaster_lib.h>
- #include "xpkmaster.h"
- #include "xpk_strings.h"
-
- struct XpkInfo DONTInfo = { 1,0,0,1,"DONT","Copy",
- 0, 0x55534552, XPKIF_PK_CHUNK|XPKIF_UP_CHUNK, 50000, 10, 50000,
- 0,0,0,0,100,0,0 /* Mode */,0,0,0,0,0,0};
-
- static LONG GetPrefsPacker(struct XpkBuffer *xbuf);
- static LONG GetPassword(struct XpkBuffer *xbuf, struct TagItem *tags);
- static struct XpkTypeData *BufRecog(ULONG, struct XpkBuffer *,
- struct XpkPrefsSemaphore *);
-
- #define ROW_OF_MINUS 0x2d2d2d2d /* '----' */
- #define PP_COOKIE 0x50503230 /* 'PP20' */
-
- LONG __asm xpkopen(register __a0 struct XpkBuffer **xbufp,
- register __a1 struct TagItem *tags, register __d2 ULONG examine A4PROTO)
- {
- struct Library *XpkSubBase;
- struct XpkBuffer *xbuf;
- struct XpkStreamHeader *globhdr;
- struct XpkFib *fib;
- LONG bytesread; /* used to be able to reset after a short read */
-
- #if defined(DEBUG) && defined(SUPPORT_A4)
- DebugRunTime("xpkopen: A4 = %ld", a4);
- #elif defined (DEBUG)
- DebugRunTime("xpkopen");
- #endif
-
- *xbufp = 0;
- if(!(xbuf = initxbuf()))
- {
- parseerrortags(tags);
- return XPKERR_NOMEM;
- }
-
- #ifdef SUPPORT_A4
- xbuf->xb_regA4 = a4;
- #endif
-
- globhdr = &xbuf->xb_Headers.h_Glob;
- fib = &xbuf->xb_Fib;
-
- if(parsebuftags(xbuf, tags, 0))
- goto Abort;
-
- *xbufp = xbuf;
- if(xbuf->xb_Flags & XMF_PACKING)
- return xpkopenwrite(xbufp, tags);
-
- if(!hookread(xbuf, XIO_READ, globhdr, 4))
- { /* Read first longword only */
- bytesread = xbuf->xb_RMsg.xmm_Size;
- if(xbuf->xb_Result != XPKERR_TRUNCATED)
- goto Abort;
- /* else handle now as uncompressed file */
- }
- else
- bytesread = 4;
-
- /**************************** Standard XPK file *********************/
- if(globhdr->xsh_Pack == XPK_COOKIE)
- { /* Standard XPK packed files */
- UWORD exthlen = 0; /* size of extended header if present */
-
- xbuf->xb_Format = XPKMODE_UPSTD;
-
- /* Read rest of the global header */
- if(!hookread(xbuf, XIO_READ, (STRPTR) globhdr + 4, sizeof(struct XpkStreamHeader) - 4))
- goto Abort;
-
- if(hchecksum((STRPTR) globhdr, sizeof(struct XpkStreamHeader)))
- {
- xbuf->xb_Result = XPKERR_CHECKSUM;
- goto Abort;
- }
-
- if(!examine && globhdr->xsh_Flags & XPKSTREAMF_PASSWORD &&
- !xbuf->xb_Password)
- {
- if((xbuf->xb_Result = GetPassword(xbuf, tags)))
- goto Abort;
- }
-
- if(globhdr->xsh_Flags & XPKSTREAMF_LONGHEADERS)
- xbuf->xb_Headers.h_LocSize = sizeof(struct XpkChunkHdrLong);
- else
- xbuf->xb_Headers.h_LocSize = sizeof(struct XpkChunkHdrWord);
-
- if(globhdr->xsh_Flags & XPKSTREAMF_EXTHEADER)
- {
- if(!hookread(xbuf, XIO_READ, &exthlen, sizeof(UWORD)))
- goto Abort;
- if(!hookread(xbuf, XIO_READ, NULL, exthlen))
- goto Abort;
- exthlen += sizeof(UWORD); /* for unwinding while XpkExamine */
- }
-
- if(!hookread(xbuf, XIO_READ, &xbuf->xb_Headers.h_Loc,
- xbuf->xb_Headers.h_LocSize)) /* first lochdr */
- goto Abort;
-
- xbuf->xb_Fib.xf_CCur = sizeof(struct XpkStreamHeader);
- updatefib(xbuf);
- xbuf->xb_InLen = xbuf->xb_Fib.xf_CLen;
-
- if(!(xbuf->xb_SubBase = XpkSubBase = opensub(xbuf, globhdr->xsh_Type)))
- goto Abort;
-
- if(globhdr->xsh_SubVrs > xbuf->xb_SubInfo->xi_LibVersion)
- {
- xbuf->xb_Result = XPKERR_OLDSUBLIB;
- goto Abort;
- }
-
- xbuf->xb_ULen = globhdr->xsh_ULen;
- xbuf->xb_Prog.xp_Activity = xbuf->xb_SubInfo->xi_UnpackMsg ?
- xbuf->xb_SubInfo->xi_UnpackMsg : strings[TXT_UNPACKING_UPPER];
- xbuf->xb_Prog.xp_PackerName = xbuf->xb_SubInfo->xi_Name;
- xbuf->xb_LastMsg = xbuf->xb_SubInfo->xi_UnpackedMsg ?
- xbuf->xb_SubInfo->xi_UnpackedMsg : strings[TXT_UNPACKED];
-
- if(globhdr->xsh_Flags & XPKSTREAMF_PASSWORD)
- xbuf->xb_Fib.xf_Flags |= XPKFLAGS_PASSWORD;
-
- if(examine && !hookread(xbuf, XIO_SEEK, 0,
- -(sizeof(struct XpkStreamHeader) + xbuf->xb_Headers.h_LocSize+exthlen)))
- goto Abort;
-
- goto Exit;
- }
-
- if(!hookread(xbuf, XIO_SEEK, 0, -bytesread))
- goto Abort;
-
- if(xbuf->xb_InLen == -1)
- {
- if(!hookread(xbuf, XIO_TOTSIZE, 0, 0)) /* get input length */
- return xbuf->xb_Result;
- else if(xbuf->xb_RMsg.xmm_Size)
- xbuf->xb_InLen = xbuf->xb_RMsg.xmm_Size;
- }
-
- #ifdef USE_POWERPACKER
- /***************************** PowerPacker file ***********************/
- if(globhdr->xsh_Pack == PP_COOKIE)
- {
- struct Library *PPBase;
- LONG outsize;
-
- xbuf->xb_Format = XPKMODE_UPPP;
-
- if(!hookread(xbuf, XIO_SEEK, 0, xbuf->xb_InLen - 4))
- goto Abort; /* 4 Bytes before EOF */
- if(!hookread(xbuf, XIO_READ, &outsize, 4))
- goto Abort;
- if(!hookread(xbuf, XIO_SEEK, 0, - (xbuf->xb_InLen - 4) - (examine<<2)))
- goto Abort; /* back to start when examine, else 4 bytes later */
-
- outsize >>= 8;
-
- #ifdef DEBUG
- DebugRunTime("xpkopen: PP, InLen %ld, OutLen %ld", xbuf->xb_InLen,
- outsize);
- #endif
-
- fib->xf_Type = XPKTYPE_PACKED;
- fib->xf_CLen = xbuf->xb_InLen;
- fib->xf_ULen = outsize;
- fib->xf_NLen = outsize + XPK_MARGIN;
- fib->xf_ID = PP_COOKIE;
- percentages(fib);
-
- if(examine)
- goto Exit;
-
- xbuf->xb_Prog.xp_Activity = strings[TXT_UNPACKING_UPPER];
- xbuf->xb_Prog.xp_PackerName = "PowerPacker";
- xbuf->xb_LastMsg = strings[TXT_UNPACKED];
- xbuf->xb_ULen = outsize;
-
- if(!(PPBase = OpenLibrary ("powerpacker.library", 0)))
- {
- xbuf->xb_Result = XPKERR_MISSINGLIB;
- goto Abort;
- }
- xbuf->xb_SubBase = PPBase;
-
- goto Exit;
- }
- #endif /* USE_POWERPACKER */
-
- /**************************** Uncompressed file *************************/
- if(examine || xbuf->xb_Flags & XMF_PASSTHRU) /* Unpacked */
- {
- xbuf->xb_Format = XPKMODE_UPUP;
-
- fib->xf_Type = XPKTYPE_UNPACKED;
- fib->xf_CLen = xbuf->xb_InLen;
- fib->xf_ULen = xbuf->xb_InLen;
- fib->xf_NLen = Min(CHUNKSIZE, xbuf->xb_InLen) + XPK_MARGIN;
- fib->xf_ID = ROW_OF_MINUS;
-
- xbuf->xb_Prog.xp_Activity = strings[TXT_READING];
- xbuf->xb_Prog.xp_PackerName = "MASTER";
- xbuf->xb_LastMsg = strings[TXT_READ];
- xbuf->xb_ULen = xbuf->xb_InLen;
-
- xbuf->xb_Result = XPKERR_OK; /* if != 0 is was XPKERR_TRUNCATED */
-
- goto Exit;
- }
-
- xbuf->xb_Result = XPKERR_NOTPACKED; /* Can't unpack, can't passthru */
-
- Abort:
- *xbufp = 0;
- return XpkClose((struct XpkFib *) xbuf);
-
- Exit:
- *xbufp = xbuf;
- return XPKERR_OK;
- }
-
- /****************************** Open for packing **************************/
- LONG xpkopenwrite(struct XpkBuffer **xbufp, struct TagItem *tags)
- {
- struct XpkBuffer *xbuf = *xbufp;
- struct XpkStreamHeader *globhdr = &xbuf->xb_Headers.h_Glob;
- struct Library *XpkSubBase;
- LONG res;
-
- xbuf->xb_Format = XPKMODE_PKSTD;
-
- if(xbuf->xb_InLen == -1)
- {
- if(!hookread(xbuf, XIO_TOTSIZE, 0, 0)) /* get input length */
- return xbuf->xb_Result;
- else if(xbuf->xb_RMsg.xmm_Size)
- xbuf->xb_InLen = xbuf->xb_RMsg.xmm_Size;
- }
-
- if(!(XpkSubBase = xbuf->xb_SubBase) && /* Do we know the sublib? */
- GetPrefsPacker(xbuf))
- { /* no sublib and no prefs packer finder */
- xbuf->xb_Result = XPKERR_BADPARAMS;
- goto Abort;
- }
-
- xbuf->xb_MinChunk = xbuf->xb_SubInfo->xi_MinPkInChunk;
-
- if(xbuf->xb_Password && !(xbuf->xb_SubInfo->xi_Flags & XPKIF_ENCRYPTION))
- {
- xbuf->xb_Result = XPKERR_NOCRYPT;
- goto Abort;
- }
-
- if(!xbuf->xb_Password && (xbuf->xb_SubInfo->xi_Flags & XPKIF_NEEDPASSWD))
- { /* automatic password requester */
- if((xbuf->xb_Result = GetPassword(xbuf, tags)))
- goto Abort;
- }
-
- if(!(xbuf->xb_Flags & XMF_LOSSYOK) &&
- xbuf->xb_SubInfo->xi_Flags & XPKIF_LOSSY)
- {
- xbuf->xb_Result = XPKERR_LOSSY;
- goto Abort;
- }
-
- if(xbuf->xb_PackingMode > 100) /* Is packing mode valid? */
- xbuf->xb_PackingMode = 100; /* Use max */
-
- if(!hookwrite(xbuf, XIO_TOTSIZE, 0, ROUNDLONG
- (xbuf->xb_InLen + (xbuf->xb_InLen >> 5)) + (XPK_MARGIN<<1)))
- goto Abort;
-
- /*********************** Find the chunk size *********************/
- if((xbuf->xb_ChunkSize == 0) &&
- ((xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_DefPkInChunk) == 0))
- xbuf->xb_ChunkSize = DEFAULTCHUNKSIZE;
- if(xbuf->xb_ChunkSize < xbuf->xb_SubInfo->xi_MinPkInChunk)
- xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_MinPkInChunk;
- if((xbuf->xb_SubInfo->xi_MaxPkInChunk) &&
- (xbuf->xb_ChunkSize > xbuf->xb_SubInfo->xi_MaxPkInChunk))
- xbuf->xb_ChunkSize = xbuf->xb_SubInfo->xi_MaxPkInChunk;
-
- /******************* Prepare global header *********************/
- globhdr->xsh_Pack = 0; /* Initialize the global header */
- globhdr->xsh_Type = xbuf->xb_SubID;
-
- if(xbuf->xb_ChunkSize > 65000)
- globhdr->xsh_Flags |= XPKSTREAMF_LONGHEADERS;
- if(xbuf->xb_Password)
- globhdr->xsh_Flags |= XPKSTREAMF_PASSWORD;
-
- xbuf->xb_Headers.h_LocSize = globhdr->xsh_Flags & XPKSTREAMF_LONGHEADERS
- ? sizeof (struct XpkChunkHdrLong)
- : sizeof (struct XpkChunkHdrWord);
-
- memset(globhdr->xsh_Initial, 0xff, 16); /* Read first 16 bytes */
-
- xbuf->xb_Prog.xp_Activity = xbuf->xb_SubInfo->xi_PackMsg ?
- xbuf->xb_SubInfo->xi_PackMsg : strings[TXT_PACKING_UPPER];
- xbuf->xb_Prog.xp_PackerName = xbuf->xb_SubInfo->xi_Name;
- xbuf->xb_LastMsg = xbuf->xb_SubInfo->xi_PackedMsg ?
- xbuf->xb_SubInfo->xi_PackedMsg : strings[TXT_PACKED];
-
- Abort:
- xbuf->xb_Fib.xf_NLen = Min(xbuf->xb_InLen - xbuf->xb_Fib.xf_UCur,
- xbuf->xb_ChunkSize);
-
- if((res = xbuf->xb_Result))
- res = XpkClose((struct XpkFib *) xbuf);
-
- return res;
- }
-
- typedef struct XpkTypeData * __asm (*RecogFunc) (register __a0 STRPTR,
- register __a1 STRPTR, register __a2 STRPTR, register __d0 ULONG,
- register __d1 ULONG);
-
- static LONG GetPrefsPacker(struct XpkBuffer *xbuf)
- {
- LONG ret = XPKERR_UNKNOWN;
- struct XpkPrefsSemaphore *sem;
- ULONG bufsize;
- struct XpkTypeData *td = 0;
-
- if((xbuf->xb_Flags & XMF_NOPREFS) || !(sem = GetPrefsSem()))
- return XPKERR_NOFUNC;
-
- bufsize = Min(xbuf->xb_InLen, sem->xps_RecogSize);
-
- if(sem->xps_RecogFunc && (td = BufRecog(bufsize, xbuf, sem)) ==
- (struct XpkTypeData *) 0xFFFFFFFF)
- td = BufRecog(xbuf->xb_InLen, xbuf, sem);
-
- if(!td || td == (struct XpkTypeData *) 0xFFFFFFFF)
- td = sem->xps_MainPrefs ? sem->xps_MainPrefs->xmp_DefaultType : 0;
-
- if(td)
- {
- if(td->xtd_Flags & XTD_NoPack)
- {
- xbuf->xb_Flags |= XMF_NOPACK;
- xbuf->xb_SubInfo = &DONTInfo;
- ret = XPKERR_OK;
- }
- else if(!(td->xtd_Flags & XTD_ReturnError))
- {
- struct Library *XpkSubBase;
- struct XpkInfo *subinfo;
-
- if((XpkSubBase = opensub(xbuf, td->xtd_StdID)))
- {
- ret = XPKERR_OK;
- subinfo = XpksPackerInfo();
-
- xbuf->xb_ChunkSize = td->xtd_ChunkSize;
- xbuf->xb_PackingMode = ( td->xtd_Mode ? td->xtd_Mode :
- subinfo->xi_DefMode);
- // if(!(xbuf->xb_Password) && td->xtd_Password &&
- // (xbuf->xb_PasswordSize = strlen(td->xtd_Password)))
- // {
- // /* we need a buffer including end byte! --> ++size */
- // if(!(xbuf->xb_Password = (STRPTR)
- // AllocMem(++xbuf->xb_PasswordSize, MEMF_PUBLIC)))
- // ret = XPKERR_NOMEM;
- // else
- // {
- // xbuf->Flags |= XMF_OWNPASSWORD;
- // CopyMem(td->xtd_Password, xbuf->xb_Password, xbuf->xb_PasswordSize);
- // }
- // }
- }
- }
- }
-
- if(td->xtd_Memory && td->xtd_MemorySize)
- FreeMem(td->xtd_Memory, td->xtd_MemorySize);
-
- ReleaseSemaphore((struct SignalSemaphore *) sem);
- return ret;
- }
-
- static LONG GetPassword(struct XpkBuffer *xbuf, struct TagItem *tags)
- {
- if(xbuf->xb_Flags & XMF_AUTOPASSWD)
- {
- if(!(xbuf->xb_Password = (STRPTR) AllocMem(AUTO_PASS_SIZE, MEMF_PUBLIC)))
- return XPKERR_NOMEM;
- xbuf->xb_PasswordSize = AUTO_PASS_SIZE;
- xbuf->xb_Flags |= XMF_OWNPASSWORD; /* must be freed later */
-
- if((xbuf->xb_Result = XpkPassRequestTags(XPK_PasswordBuf,
- xbuf->xb_Password, XPK_PassBufSize, xbuf->xb_PasswordSize, TAG_MORE,
- tags, TAG_DONE)))
- return xbuf->xb_Result;
- else
- {
- #ifdef DEBUG
- DebugRunTime("GetPassword: %s", xbuf->xb_Password);
- #endif
- return XPKERR_OK;
- }
- }
- return XPKERR_NEEDPASSWD;
- }
-
- static struct XpkTypeData *BufRecog(ULONG bufsize, struct XpkBuffer *xbuf,
- struct XpkPrefsSemaphore *sem)
- {
- STRPTR bufptr;
- struct XpkTypeData *ret = 0;
-
- if((bufptr = hookread(xbuf, XIO_READ, 0, bufsize)))
- {
- ret = (((RecogFunc) sem->xps_RecogFunc) (bufptr, xbuf->xb_InName,
- xbuf->xb_Prog.xp_FileName, bufsize, xbuf->xb_InLen));
- hookread(xbuf, XIO_SEEK, 0, -bufsize);
- }
- return ret;
- }
-
- #endif /* XPKMASTER_OPEN_C */
-